home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / src / udev-watchdog.c
Encoding:
C/C++ Source or Header  |  2012-08-03  |  4.3 KB  |  176 lines

  1. /*
  2.  * Copyright (C) 2004-2009 Kay Sievers <kay.sievers@vrfy.org>
  3.  *
  4.  * + Trimmed from udev-149. Fixed passing of devtype parameter.
  5.  *
  6.  * This program is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. #ifndef _POSIX_C_SOURCE
  21. #define _POSIX_C_SOURCE 1
  22. #ifndef _BSD_SOURCE
  23. #define _BSD_SOURCE
  24. #endif
  25. #endif
  26.  
  27. #include <unistd.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31. #include <string.h>
  32. #include <fcntl.h>
  33. #include <errno.h>
  34. #include <signal.h>
  35. #include <getopt.h>
  36. #include <sys/time.h>
  37. #include <sys/socket.h>
  38. #include <sys/un.h>
  39. #include <sys/select.h>
  40. #include <linux/types.h>
  41. #include <linux/netlink.h>
  42. #include <libudev.h>
  43.  
  44. static volatile sig_atomic_t udev_exit;
  45.  
  46. static void sig_handler(int signum)
  47. {
  48.     if (signum == SIGINT || signum == SIGTERM)
  49.         udev_exit = 2;
  50. }
  51.  
  52. static int print_device(struct udev_device *device, const char *f_action, const char *f_devsuffix)
  53. {
  54.     struct timeval  tv;
  55.  
  56.     const  char *action  = udev_device_get_action(device);
  57.     const  char *devpath = udev_device_get_devpath(device);
  58.     size_t f_len, d_len;
  59.  
  60.     gettimeofday(&tv, NULL);
  61.     printf("%lu.%06u %s %s\n",
  62.            (unsigned long) tv.tv_sec, (unsigned int) tv.tv_usec,
  63.            action, devpath);
  64.  
  65.     if (! strcmp(f_action, action)) {
  66.         f_len = strlen(f_devsuffix);
  67.         d_len = strlen(devpath);
  68.  
  69.         if (d_len >= f_len && !strcmp(devpath+(d_len-f_len), f_devsuffix))
  70.             return 1;
  71.     }
  72.  
  73.     return 0;
  74. }
  75.  
  76. int main(int argc, char *argv[])
  77. {
  78.     int rc = 0;
  79.  
  80.     struct udev *udev;
  81.  
  82.     struct sigaction act;
  83.     sigset_t mask;
  84.     struct udev_monitor *kernel_monitor = NULL;
  85.     fd_set readfds;
  86.  
  87.     const char *filter_subsys    = "block";
  88.     /* const char *filter_devtype   = "partition"; */
  89.     const char *filter_devsuffix;
  90.     const char *filter_devtype;
  91.     const char *filter_action;
  92.  
  93.     udev = udev_new();
  94.     if (udev == NULL)
  95.         goto out2;
  96.  
  97.     if (argc != 3)
  98.         goto out2;
  99.  
  100.     filter_devsuffix = argv[1];
  101.     filter_devtype = argv[2];
  102.  
  103.     if (strcmp(filter_devtype, "cd") == 0) {
  104.         filter_action = "change";
  105.     } else if (strcmp(filter_devtype, "disk") == 0) {
  106.         filter_action = "remove";
  107.     }
  108.  
  109.     /* set signal handlers */
  110.     memset(&act, 0x00, sizeof(struct sigaction));
  111.     act.sa_handler = sig_handler;
  112.     sigemptyset(&act.sa_mask);
  113.     act.sa_flags = SA_RESTART;
  114.     sigaction(SIGINT, &act, NULL);
  115.     sigaction(SIGTERM, &act, NULL);
  116.     sigemptyset(&mask);
  117.     sigaddset(&mask, SIGINT);
  118.     sigaddset(&mask, SIGTERM);
  119.     sigprocmask(SIG_UNBLOCK, &mask, NULL);
  120.  
  121.     kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
  122.     if (kernel_monitor == NULL) {
  123.         fprintf(stderr, "error: unable to create netlink socket\n");
  124.         rc = 3;
  125.         goto out;
  126.     }
  127.  
  128.     if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, filter_subsys, NULL /* filter_devtype */) < 0)
  129.         fprintf(stderr, "error: unable to apply subsystem filter '%s:%s'\n", filter_subsys, "NULL" /* filter_devtype */);
  130.  
  131.     if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
  132.         fprintf(stderr, "error: unable to subscribe to kernel events\n");
  133.         rc = 4;
  134.         goto out;
  135.     }
  136.  
  137.     while (!udev_exit) {
  138.         int fdcount;
  139.  
  140.         FD_ZERO(&readfds);
  141.         if (kernel_monitor != NULL)
  142.             FD_SET(udev_monitor_get_fd(kernel_monitor), &readfds);
  143.  
  144.         fdcount = select(udev_monitor_get_fd(kernel_monitor)+1,
  145.                  &readfds, NULL, NULL, NULL);
  146.         if (fdcount < 0) {
  147.             if (errno != EINTR)
  148.                 fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno));
  149.             continue;
  150.         }
  151.  
  152.         if ((kernel_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(kernel_monitor), &readfds)) {
  153.             struct udev_device *device;
  154.  
  155.             device = udev_monitor_receive_device(kernel_monitor);
  156.             if (device == NULL)
  157.                 continue;
  158.             if (print_device(device, filter_action, filter_devsuffix))
  159.                 udev_exit = 1;
  160.  
  161.             udev_device_unref(device);
  162.         }
  163.     }
  164.  
  165. out:
  166.     udev_monitor_unref(kernel_monitor);
  167.  
  168. out2:
  169.     udev_unref(udev);
  170.  
  171.     if (udev_exit == 2)
  172.         rc = 1;
  173.  
  174.     return rc;
  175. }
  176.